package vn.edu.uit.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URLEncoder;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;


/**
 * The Class UITRestClient.
 */
public class UITRestClient {
	
	/**
	 * The Enum RequestMethod.
	 */
	public enum RequestMethod
	{
	    
    	/** The get. */
    	GET,
	    
    	/** The post. */
    	POST
	}
	 
 	/** The params. */
 	public ArrayList <NameValuePair> params;
	    
    	/** The headers. */
    	private ArrayList <NameValuePair> headers;

	    /** The url. */
    	private String url;

	    /** The response code. */
    	private int responseCode;
	    
    	/** The message. */
    	private String message;

	    /** The response. */
    	private String response;

	    /**
    	 * Gets the response.
    	 *
    	 * @return the response
    	 */
    	public String getResponse() {
	        return response;
	    }

	    /**
    	 * Gets the error message.
    	 *
    	 * @return the error message
    	 */
    	public String getErrorMessage() {
	        return message;
	    }

	    /**
    	 * Gets the response code.
    	 *
    	 * @return the response code
    	 */
    	public int getResponseCode() {
	        return responseCode;
	    }

	    /**
    	 * Instantiates a new  rest client.
    	 *
    	 * @param url the url
    	 */
    	public UITRestClient(String url)
	    {
//	    	StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
//			.detectNetwork().penaltyDialog().build());
	        this.url = url;
	        params = new ArrayList<NameValuePair>();
	        headers = new ArrayList<NameValuePair>();
	    }

	    /**
    	 * Adds the param.
    	 *
    	 * @param name the name
    	 * @param value the value
    	 */
    	public void AddParam(String name, String value)
	    {
	        params.add(new BasicNameValuePair(name, value));
	    }

	    /**
    	 * Adds the header.
    	 *
    	 * @param name the name
    	 * @param value the value
    	 */
    	public void AddHeader(String name, String value)
	    {
	        headers.add(new BasicNameValuePair(name, value));
	    }

	    /**
    	 * Execute.
    	 *
    	 * @param method the method
    	 * @throws Exception the exception
    	 */
    	public void Execute(RequestMethod method) throws Exception
	    {
	        switch(method) {
	            case GET:
	            {
	                //add parameters
	                String combinedParams = "";
	                if(!params.isEmpty()){
	                    combinedParams += "?";
	                    for(NameValuePair p : params)
	                    {
	                        String paramString = p.getName() + "=" + URLEncoder.encode(p.getValue(),"UTF-8");
	                        if(combinedParams.length() > 1)
	                        {
	                            combinedParams  +=  "&" + paramString;
	                        }
	                        else
	                        {
	                            combinedParams += paramString;
	                        }
	                    }
	                }

	                HttpGet request = new HttpGet(url + combinedParams);
	                //add headers
	                for(NameValuePair h : headers)
	                {
	                    request.addHeader(h.getName(), h.getValue());
	                }
	                executeRequest(request, url);
	                break;
	            }
	            case POST:
	            {
	                HttpPost request = new HttpPost(url);

	                //add headers
	                for(NameValuePair h : headers)
	                {
	                    request.addHeader(h.getName(), h.getValue());
	                }

	                if(!params.isEmpty()){
	                    request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
	                }
	                executeRequest(request, url);
	                break;
	            }
	        }
	    }

	    /**
    	 * Execute request.
    	 *
    	 * @param request the request
    	 * @param url the url
    	 */
    	private void executeRequest(HttpUriRequest request, String url)
	    {
	        HttpClient client = new DefaultHttpClient();

	        HttpResponse httpResponse;

	        try {
	            httpResponse = client.execute(request);
	            responseCode = httpResponse.getStatusLine().getStatusCode();
	            message = httpResponse.getStatusLine().getReasonPhrase();

	            HttpEntity entity = httpResponse.getEntity();

	            if (entity != null) {

	            	
	                InputStream instream = entity.getContent();
	                response = convertStreamToString(instream);
	                
	                //Only reposse
	                try{
		                DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
		                DocumentBuilder builder = domFactory.newDocumentBuilder();
		                Document doc =  builder.parse(new InputSource(new StringReader(response)));
		                NodeList nl = doc.getElementsByTagName("response");    
		                Element firstNameElement = (Element)nl.item(0);
		                response = firstNameElement.getChildNodes().item(0).getNodeValue();
		                
	                }catch(Exception e){
	                }
	                // Closing the input stream will trigger connection release
	                instream.close();
	            }

	        } catch (ClientProtocolException e)  {
	            //client.getConnectionManager().shutdown();
	            e.printStackTrace();
	        } catch (IOException e) {
	            //client.getConnectionManager().shutdown();
	            e.printStackTrace();
	        }
	    }

	    /**
    	 * Convert stream to string.
    	 *
    	 * @param is the is
    	 * @return the string
    	 */
    	private static String convertStreamToString(InputStream is) {

	        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
	        StringBuilder sb = new StringBuilder();

	        String line = null;
	        try {
	            while ((line = reader.readLine()) != null) {
	                sb.append(line + "\n");
	            }
	        } catch (IOException e) {
	            e.printStackTrace();
	        } finally {
	            try {
	                is.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	        
	        return sb.toString();
	    }
}
